package channel;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.ArrayList;

public class ChannelInterface extends Thread {

    private Socket socket;
    private ArrayList<ChannelItem> sockets;
    private String motd;

    public ChannelInterface(Socket socket, ArrayList<ChannelItem> sockets, String motd) {
        this.socket = socket;
        this.sockets = sockets;
        this.motd = motd;
    }

    @Override
    public void run() {
        takeInput();
    }

    private void takeInput() {
        try {
            BufferedReader inFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            DataOutputStream outToClient = new DataOutputStream(socket.getOutputStream());

            while (true) {
                String requestMessageLine = inFromClient.readLine();
                System.out.println(requestMessageLine);

                if (requestMessageLine != null) {
                    if (requestMessageLine.equals("GETSERVERS")) {
                        getServers(outToClient);
                    } // Add server syntax: ADDSERVER servername and details//#PLAYERS
                    else if (requestMessageLine.startsWith("ADDSERVER ")) {
                        addServer(requestMessageLine.substring(10), outToClient);
                    } // Update servers player count
                    else if (requestMessageLine.startsWith("SETPLAYERS ")) {
                        setPlayers(requestMessageLine.substring(11));
                    } else if (requestMessageLine.startsWith("GETMOTD")) {
                        getMOTD(outToClient);
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void getServers(DataOutputStream outToClient) throws IOException {
        String servers = sockets.size() + "\r\n";
        for (int x = 0; x < sockets.size(); x++) {
            servers = servers.concat(sockets.get(x).getIP().concat(
                    " ".concat(String.valueOf(sockets.get(x).getServerPort()).concat(
                    " `".concat(sockets.get(x).getServerName().concat("`".concat(
                    " `".concat(sockets.get(x).getAdvName().concat("`".concat(
                    " `".concat(sockets.get(x).getAdvDesc().concat("`".concat(
                    " `".concat(String.valueOf(sockets.get(x).getAdvVers()).concat("`".concat(
                    " `".concat(String.valueOf(sockets.get(x).getCurrentPlayers()).concat("`".concat(
                    " `".concat(String.valueOf(sockets.get(x).getMaxPlayers()).concat("`".concat(
                    "\r\n"))))))))))))))))))))));
        }
        outToClient.writeBytes(servers);
    }

    private void getMOTD(DataOutputStream outToClient) throws IOException {
        outToClient.writeBytes(motd);
    }

    private void addServer(String serverDets, DataOutputStream outToClient) throws IOException {
        // Add server syntax: `server name` `adventure name` `adventure description` `adventure version` `maxCapacity`
        boolean readingField = false;
        String field = "";
        int port = Integer.parseInt(serverDets.split(" ")[0]);
        ArrayList<String> fields = new ArrayList<String>();
        for (int x = 0; x < serverDets.length(); x++) {
            if (serverDets.charAt(x) == '`') {
                if (readingField) {
                    readingField = false;
                    fields.add(field);
                    field = "";
                } else {
                    readingField = true;
                }
            } else {
                if (readingField) {
                    field = field + serverDets.charAt(x);
                }
            }
        }

        if (fields.size() == 5) {
            boolean alreadyExists = false;
            for (int x = 0; x < sockets.size() & !alreadyExists; x++) {
                if (sockets.get(x).getIP().equals(socket.getInetAddress().getHostAddress())) {
                    alreadyExists = true;
                }
            }
            if (!alreadyExists) {
                try {
                    sockets.add(new ChannelItem(socket, port, fields.get(0), fields.get(1),
                            fields.get(2), Double.parseDouble(fields.get(3)), Integer.parseInt(fields.get(4))));
                } catch (NumberFormatException e) {
                    e.printStackTrace();
                    sockets.add(new ChannelItem(socket, port, fields.get(0), fields.get(1),
                            fields.get(2), 1, 24));
                }
            }
        }
        outToClient.writeBytes(true + "\r\n");
    }

    private void setPlayers(String num) {
        boolean match = false;
        for (int x = 0; x < sockets.size() && !match; x++) {
            if (sockets.get(x).getIP().equals(socket.getInetAddress().toString().substring(1))) {
                match = true;
                try {
                    int players = Integer.parseInt(num);
                    sockets.get(x).setPlayerCount(players);
                } catch (NumberFormatException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
